function modifPropsData(vnode, key, value) {
  if (!vnode.componentOptions) {
    return
  }
  const propsData = vnode.componentOptions.propsData || {}
  propsData[key] = [value, propsData[key]].join(' ').replace(/^ /, '')
}
function setPropsData(vnode, key, value) {
  if (!vnode.componentOptions) {
    return
  }
  const propsData = vnode.componentOptions.propsData || {}
  if (!propsData[key]) {
    propsData[key] = value
  }
}
// 如果listItem上设置了span，则使用该span
function setSpan(vnode, span) {
  if (vnode.data.attrs && vnode.data.attrs.span) {
    return vnode.data.attrs.span
  } else {
    return span
  }
}

export default {
  name: 'List',
  props: {
    column: {
      type: Number,
      default: 1
    },
    gutter: {
      type: Number,
      default: 12
    },
    type: {
      type: String,
      default: 'flex'
    },
    wrap: {
      type: String,
      default: 'wrap'
    },
    align: {
      type: String,
      default: 'stretch'
    },
    justify: {
      type: String,
      default: ''
    },
    sep: {
      type: String,
      default: ''
    },
    itemClassName: {
      type: String,
      default: ''
    },
    labelClassName: {
      type: String,
      default: 'label-style'
    },
    labelWidth: {
      type: String,
      default: 'auto'
    },
    valueClassName: {
      type: String,
      default: ''
    },
    defaultValue: {
      type: String,
      default: ''
    },
    xs: {
      type: [Number, Object],
      default: () => ({})
    },
    sm: {
      type: [Number, Object],
      default: () => ({})
    },
    md: {
      type: [Number, Object],
      default: () => ({})
    },
    lg: {
      type: [Number, Object],
      default: () => ({})
    },
    xl: {
      type: [Number, Object],
      default: () => ({})
    },
    // 校验相关
    mode: {
      type: Object,
      default: () => ({})
    },
    rules: {
      type: Object,
      default: () => ({})
    }
  },
  created() {
    this.__children = {}
  },
  render(h) {
    const span = Math.floor(24 / this.column)
    const childrens = this.$scopedSlots.default ? this.$scopedSlots.default() : []
    const items = []
    const __children = {}
    for (const children of childrens) {
      if (!children.tag) {
        continue
      }

      modifPropsData(children, 'sep', this.sep)
      modifPropsData(children, 'labelClassName', this.labelClassName)
      modifPropsData(children, 'valueClassName', this.valueClassName)
      modifPropsData(children, 'itemClassName', this.itemClassName)
      modifPropsData(children, 'defaultValue', this.defaultValue)
      setPropsData(children, 'labelWidth', this.labelWidth)

      const childPropsData = (children.componentOptions || {}).propsData || {}
      if (childPropsData.prop && this.rules && this.rules[childPropsData.prop]) {
        setPropsData(children, 'rules', this.rules[childPropsData.prop])
      }
      if (childPropsData.prop) {
        __children[childPropsData.prop] = children
        setPropsData(children, 'propValue', this.mode[childPropsData.prop])
      }
      if (!children.key && childPropsData.label) {
        children.key = childPropsData.prop + childPropsData.label
      }

      const elCol = h('el-col', {
        props: {
          span: setSpan(children, span),
          xs: this.xs,
          sm: this.sm,
          md: this.md,
          lg: this.lg,
          xl: this.xl
        }
      }, [children])
      if (children.data.directives) {
        if (!elCol.data) {
          elCol.data = {}
        }
        if (!elCol.data.directives) {
          elCol.data.directives = []
        }
        elCol.data.directives = [...elCol.data.directives, ...children.data.directives]
      }
      items.push(elCol)
    }
    const style = {}
    if (this.type === 'flex') {
      style.flexWrap = this.wrap
    }

    this.__children = __children

    return h('el-row', {
      props: {
        gutter: this.gutter,
        type: this.type,
        justify: this.justify,
        align: this.align
      },
      style
    }, items)
  },
  methods: {
    validate(showErr = false) {
      const d = {}
      const errMsgs = []
      Object.assign(d, this.mode)
      let isOK = true
      for (const c of Object.values(this.__children)) {
        if (c.componentInstance && c.componentInstance.validate instanceof Function) {
          const { result, errMsg } = c.componentInstance.validate(d)
          if (!result && isOK) {
            isOK = false
          }
          if (errMsg) {
            errMsgs.push(errMsg)
          }
        }
      }
      if (!isOK && showErr) {
        this.$message.warning({
          dangerouslyUseHTMLString: true,
          message: errMsgs.join('<br>')
        })
      }
      return isOK
    },
    clearFields() {
      for (const c of Object.values(this.__children)) {
        if (c.componentInstance && c.componentInstance.clearErrMsg instanceof Function) {
          c.componentInstance.clearErrMsg()
        }
      }
    }
  }
}
